#include "Mario.h"
#include "Resource.h"
#include "Bullet.h"

/**--------------------------------------------------------
*Description : Constructor
*Method name : Mario
*Parameters :  float x, float y, bool isAi
*Return value :
--------------------------------------------------------**/
Mario::Mario(LPDIRECT3DDEVICE9 d3ddv,  LPDIRECT3DSURFACE9 backBuffer, LPD3DXSPRITE spriteHandler, float x, float y, MarioGame* Game_Mario, int Obj_state, int Direction)
{
	this->game_Mario = Game_Mario;

	this->d3ddv = d3ddv;
	this->backBuffer = backBuffer;
	this->spriteHandler = spriteHandler;

	p_spriteSmall = new Sprite(spriteHandler, ResourceMng::GetInst(d3ddv, backBuffer)->GetTexture(L"..\\Resources\\Images\\mario_small.png"), 125, 0);
	p_spriteBig = new Sprite(spriteHandler, ResourceMng::GetInst(d3ddv, backBuffer)->GetTexture(L"..\\Resources\\Images\\mario_big.png"), 125, 0);
	p_spriteBullet = new Sprite(spriteHandler, ResourceMng::GetInst(d3ddv, backBuffer)->GetTexture(L"..\\Resources\\Images\\mario_bullet.png"), 125, 0);
	p_spriteLight = new Sprite(spriteHandler, ResourceMng::GetInst(d3ddv, backBuffer)->GetTexture(L"..\\Resources\\Images\\mario_small_light.png"), 125, 0);
	p_sprite = p_spriteSmall;//new Sprite(this->spriteHandler, ResourceMng::GetInst(this->d3ddv, this->backBuffer)->GetTexture(L"..\\Resources\\Images\\mario_big.png"), 125, 0);

	is_turn_left = false;
	is_jump = false;

	isSmall = true;			//mario con nho
	isShoot = false;		//chua co bullet
	isHasStar = false;		//chua co sao ba dao
	isMoveDown = false;		//chua chuoi cong
	isGravity = true;		//co Trong luc
	isDieFall = false;

	pos_x = x;
	pos_y = y;
	_xOld = x;
	_yOld = y;

	veloc_x = 0;
	veloc_y = 0;
	accel_x = 0;
	accel_y = 0;


	width = p_sprite->getTexture()->getWidth();
	height = p_sprite->getTexture()->getHeight();

	timeBullet = 0;
	timeTransferState = 0;
	countFrame = 0;

	bullet = NULL;
	bullet2 = NULL;

	this->obj_state = Obj_state;
	this->direction = Direction;
	if (obj_state == MS_NORMAL)
	{
		if (direction == 1)			//mario nho
		{
			p_sprite = p_spriteSmall;
			isSmall = true;
		} 
		else if (direction == 21)	//mario to
		{
			p_sprite = p_spriteBig;
			isSmall = false;
		}
		else if (direction == 22)	//mario to, co bullet
		{
			p_sprite = p_spriteBullet;
			isSmall = false;
			isShoot = true;
		}
	} 
	else if (obj_state == MS_HASSTAR)
	{
		timeProtect = 0;
		countFrame = 0;
		isHasStar = true;
		if (direction == 1)			//mario nho
		{
			p_sprite = p_spriteSmall;
			isSmall = true;
		} 
		else if (direction == 21)	//mario to
		{
			p_sprite = p_spriteBig;
			isSmall = false;
		}
		else if (direction == 22)	//mario to, co bullet
		{
			p_sprite = p_spriteBullet;
			isSmall = false;
			isShoot = true;
		}
	}
	else if (obj_state == MS_PROTECT)
	{
		timeProtect = 0;
		countFrame = 0;

		isHasStar = false;
		if (direction == 1)			//mario nho
		{
			p_sprite = p_spriteSmall;
			isSmall = true;
		} 
		else if (direction == 21)	//mario to
		{
			p_sprite = p_spriteBig;
			isSmall = false;
		}
		else if (direction == 22)	//mario to, co bullet
		{
			p_sprite = p_spriteBullet;
			isSmall = false;
			isShoot = true;
		}
	}
	else if (obj_state == MS_DIE)
	{
		p_sprite = p_spriteSmall;
		//if (_turnLeft == true)
		if (direction == 1)		//left
		{
			p_sprite->setFrame(6,6);
		} 
		else if (direction == 2)	//right
		{
			p_sprite->setFrame(4,4);
		}
		veloc_y = 1.5;
		accel_y = GRAVITY;
	} 
	else if (obj_state == MS_SMALLTOBIG)
	{
		//_y = _y + 30;
		isSmall = false;
		timeTransferState = 0;
		countFrame = 0;
		p_sprite = p_spriteSmall;
		//if (_turnLeft == true)
		if (direction == 1)		//left
		{
			is_turn_left = true;
			//_sprite->SetFrame(9, 11);
		} 
		else if (direction == 2)	//right
		{
			is_turn_left = false;
			//_sprite->SetFrame(0, 2);
		}
	}
	else if (obj_state == MS_BIGTOSMALL)
	{
		pos_y = pos_y - 30;
		isSmall = true;
		timeTransferState = 0;
		countFrame = 0;
		p_sprite = p_spriteBig;
		//if (_turnLeft == true)
		if (direction == 1)		//left
		{
			is_turn_left = true;
			//_sprite->SetFrame(9, 11);
		} 
		else if (direction == 2)	//right
		{
			is_turn_left = false;
			//_sprite->SetFrame(0, 2);
		}
	}
	else if (obj_state == MS_BULLETTOSMALL)
	{
		pos_y = pos_y - 30;
		isSmall = true;
		isShoot = false;
		timeTransferState = 0;
		countFrame = 0;
		p_sprite = p_spriteBig;
		//if (_turnLeft == true)
		if (direction == 1)		//left
		{
			is_turn_left = true;
			//_sprite->SetFrame(9, 11);
		} 
		else if (direction == 2)	//right
		{
			is_turn_left = false;
			//_sprite->SetFrame(0, 2);
		}
	}
	else if (obj_state == MS_BIGTOBULLET)
	{
		isSmall = false;
		isShoot = true;
		timeTransferState = 0;
		countFrame = 0;
		p_sprite = p_spriteBig;
		//if (_turnLeft == true)
		if (direction == 1)		//left
		{
			is_turn_left = true;
			//_sprite->SetFrame(9, 11);
		} 
		else if (direction == 2)	//right
		{
			is_turn_left = false;
			//_sprite->SetFrame(0, 2);
		}
	}

	
}


/**--------------------------------------------------------
*Description : Destructor
*Method name : Mario
*Parameters :   
*Return value :
--------------------------------------------------------**/
Mario::~Mario(void)
{
	if (p_sprite)
	{
		delete p_sprite;
	}

	if (bullet)
	{
		delete bullet;
	}
	if (bullet2)
	{
		delete bullet2;
	}
}


/**--------------------------------------------------------
*Description : Update mario theo thoi gian
*Method name : Update
*Parameters :  int time
*Return value :void
--------------------------------------------------------**/
//void Mario::update(int time)
//{
//	//velocity
//	pos_x += veloc_x * time;
//	pos_y += veloc_y * time;
//
//	if(veloc_x > 0)
//	{
//		veloc_x -= ACCEL_X * time;
//		if(veloc_x < 0) veloc_x = 0;
//	}
//	else
//	{
//		veloc_x += ACCEL_X * time;
//		if(veloc_x > 0) veloc_x = 0;
//	}
//	
//	veloc_y -= GRAVITY * time;
//	if(pos_y <= BOTTOM - p_sprite->getTexture()->getHeight())//_sprRight->texture->_Height
//	{
//		veloc_y = 0;
//		is_jump = false;
//		pos_y = BOTTOM - p_sprite->getTexture()->getHeight() - 1;
//	}
//
//	//sprite update
//	if(veloc_x != 0)
//		p_sprite->update(time);
//}

void Mario::update(list<Object*>* obj_list, DxInput* input, float time)
{
	switch (this->obj_state)
	{
	case MS_NORMAL:
		{
			//Update Input
			this->processInput(input);

			this->move(obj_list, time);

			if (bullet != NULL)
			{
				bullet->update(obj_list, input, time);
			}
			if (bullet2 != NULL)
			{
				bullet2->update(obj_list, input, time);
			}

			//su dung khi load map
			if (isSmall == true)
			{
				direction = 1;
			} 
			else
			{
				if (isShoot == false)
				{
					direction = 21;
				} 
				else
				{
					direction = 22;
				}
			}
		}
		break;

	case MS_DIE:
		//Saave map
		if (is_turn_left == true)
		{
			direction = 1;
		} 
		else
		{
			direction = 2;
		}

		veloc_y -= accel_y * time;
		pos_y += veloc_y * time + 1/2 * accel_y * time * time;
		if (pos_y <= 0)		///roi xuong ho, cuoi man hinh
		{
			changeState(MS_REMOVE);
			
			pos_y = 100;
			if (game_Mario->num_Life == 0)
			{
				//this->obj_state = MS_NORMAL;

				//this->isSmall = false;
				game_Mario->ChangeState(GS_GAMEOVER);
			}
			else
			{
				
				game_Mario->ChangeState(GS_REPLAY);
				//this->obj_state = MS_NORMAL;
				//changeState(MS_NORMAL);
				
			}
		}
		break;

	case MS_CREPTPINE:
		if (is_turn_left == true)
		{
			direction = 1;
		} 
		else
		{
			direction = 2;
		}

		veloc_y -= accel_y * time;
		pos_y += veloc_y * time + 1/2 * accel_y * time *time;
		if (pos_y <= _yOld - 64)
		{
			//changeState(MS_REMOVE);
			changeState(MS_NORMAL);
			game_Mario->ChangeState(GS_SUB_STAGE);
		}		
		break;

	case MS_INTOPINE:
		//Saave map
		if (is_turn_left == true)
		{
			direction = 1;
		} 
		else
		{
			direction = 2;
		}

		veloc_x += accel_x * time;
		pos_x += veloc_x * time + 1/2 * accel_x * time * time;

		if (pos_x >= _xOld)
		{
			//changeState(MS_REMOVE);
			//changeState(MS_NORMAL);
			//game_Mario->subMapToMap = true;
			game_Mario->ChangeState(GS_RETURN_STAGE);
		} 
		break;

	case MS_SMALLTOBIG:
		if (is_turn_left == true)
		{
			direction = 1;
		} 
		else
		{
			direction = 2;
		}
		timeTransferState += time;
		if (timeTransferState > 40)
		{
			timeTransferState = 0;
			countFrame++;
			if (countFrame % 2 != 0)		//frame le
			{
				pos_y = pos_y + 30;
				p_sprite = p_spriteBig;
				if (is_turn_left == true)
				{
					p_sprite->setFrame(8, 9);
				}
				else
				{
					p_sprite->setFrame(1, 2);
				}
			}
			else
			{
				pos_y = pos_y - 30;
				p_sprite = p_spriteSmall;
				if (is_turn_left == true)
				{
					p_sprite->setFrame(10,11);
				} 
				else
				{
					p_sprite->setFrame(0,1);
				}
			}
			if (countFrame > 8)
			{
				//ChangeSprite(_spriteBig);
				p_sprite = p_spriteBig;
				changeState(MS_NORMAL);
			}
		}
		break;


	case MS_BIGTOSMALL:
		if (is_turn_left == true)
		{
			direction = 1;
		} 
		else
		{
			direction = 2;
		}
		timeTransferState += time;
		if (timeTransferState > 40)
		{
			timeTransferState = 0;
			countFrame++;
			if (countFrame % 2 != 0)		//frame le
			{
				pos_y = pos_y - 30;
				p_sprite = p_spriteSmall;
				if (is_turn_left == true)
				{
					p_sprite->setFrame(10,11);
				} 
				else
				{
					p_sprite->setFrame(0,1);
				}
			}
			else								//frame chan
			{
				pos_y = pos_y + 30;
				p_sprite = p_spriteBig;
				if (is_turn_left == true)
				{
					p_sprite->setFrame(8,9);
				} 
				else
				{
					p_sprite->setFrame(1,2);
				}

			}
			/*_xOld = pos_x;
			_yOld = pos_y;*/
			if (countFrame > 8)
			{				
				p_sprite = p_spriteSmall;
				changeState(MS_PROTECT);
			}
		}

		break;

	case MS_BULLETTOSMALL:
		if (is_turn_left == true)
		{
			direction = 1;
		} 
		else
		{
			direction = 2;
		}
		timeTransferState += time;
		if (timeTransferState > 40)
		{
			timeTransferState = 0;
			countFrame++;
			if (countFrame % 2 != 0)		//frame le
			{
				pos_y = pos_y - 30;
				p_sprite = p_spriteSmall;
				if (is_turn_left == true)
				{
					p_sprite->setFrame(10,11);
				} 
				else
				{
					p_sprite->setFrame(0,1);
				}
			}
			else								//frame chan
			{
				pos_y = pos_y + 30;
				p_sprite = p_spriteBullet;
				if (is_turn_left == true)
				{
					p_sprite->setFrame(8,9);
				} 
				else
				{
					p_sprite->setFrame(1,2);
				}

			}
			if (countFrame > 8)
			{
				p_sprite = p_spriteSmall;
				changeState(MS_PROTECT);
			}
		}
		/*_xOld = pos_x;
		_yOld = pos_y;*/
		break;

	case MS_BIGTOBULLET:
		if (is_turn_left == true)
		{
			direction = 1;
		} 
		else
		{
			direction = 2;
		}
		timeTransferState += time;
		if (timeTransferState > 40)
		{
			timeTransferState = 0;
			countFrame++;
			if (countFrame % 2 != 0)		//frame le
			{
				p_sprite = p_spriteBullet;
				if (is_turn_left == true)
				{
					p_sprite->setFrame(8,9);
				} 
				else
				{
					p_sprite->setFrame(1,2);
				}
			}
			else								//frame chan
			{
				p_sprite = p_spriteBig;
				if (is_turn_left == true)
				{
					p_sprite->setFrame(8,9);
				} 
				else
				{
					p_sprite->setFrame(1,2);
				}
			}
			if (countFrame > 8)
			{				
				p_sprite = p_spriteBullet;
				changeState(MS_NORMAL);
			}
		}
		break;

	case MS_PROTECT:
		//processInput(input);
		//move(obj_list, time);

		if (is_turn_left == true)
		{
			direction = 1;
		} 
		else
		{
			direction = 2;
		}

		timeProtect += time;
		if (timeProtect > 40)
		{
			timeProtect = 0;
			countFrame++;
			if (countFrame % 2 != 0)		//frame le
			{
				p_sprite = p_spriteLight;

			}
			else								//frame chan
			{
				p_sprite = p_spriteSmall;

			}
			/*_xOld = pos_x;
			_yOld = pos_y;*/
			if (countFrame > 43)
			{
				p_sprite = p_spriteSmall;

				changeState(MS_NORMAL);
			}
		}

		break;

	case MS_HASSTAR:
		processInput(input);
		move(obj_list, time);
		//UpdateNormal(staObjs, dynObjs, input, time);

		timeProtect += time;
		if (timeProtect > 40)
		{
			timeProtect = 0;
			countFrame++;
			if (countFrame % 2 != 0)		//frame le
			{
				if (isSmall == true)
				{
					p_sprite = p_spriteLight;
				} 
				else
				{
					p_sprite = p_spriteBig;
				}
			}
			else								//frame chan
			{
				if (isSmall == true)
				{
					p_sprite = p_spriteSmall;
				} 
				else
				{
					p_sprite = p_spriteBullet;
				}
			}
			if (countFrame > 243)
			{
				isHasStar = false;
				if (isSmall == true)
				{
					p_sprite = p_spriteSmall;
				} 
				else
				{
					if (isShoot == true)
					{
						p_sprite = p_spriteBullet;
					} 
					else
					{
						p_sprite = p_spriteBig;
					}
				}
				changeState(MS_NORMAL);
			}
		}
		break;

	}


	//sprite update
	//if(veloc_x != 0)
	p_sprite->update(time);
}


void Mario::move(list<Object*>* obj_list, float time)
{
	timeBullet += time;
	width = p_sprite->getTexture()->getWidth();
	height = p_sprite->getTexture()->getHeight();

	Object *obj;
	list<Object*>::iterator i_obj;

	_xOld = pos_x;
	_yOld = pos_y;

	//Truc X
	veloc_x += accel_x * time;
	if (veloc_x > MARIO_VX_MAX)
	{
		veloc_x = MARIO_VX_MAX;
	} 
	else if (veloc_x < -MARIO_VX_MAX)
	{
		veloc_x = - MARIO_VX_MAX;
	}
	pos_x += veloc_x * time + 1.0f/2.0f * accel_x * time * time;

	//Truc Y
	if (isGravity == false)
	{
		accel_y = 0;
	}
	else
	{
		accel_y = GRAVITY;
	}
	//accel_y = GRAVITY;	
	veloc_y -= accel_y * time;
	pos_y += veloc_y * time + 1.0f/2.0f * accel_y * time * time;


	/*
	*	Kiem tra va cham voi cac doi tuong tinh
	*/
	for (i_obj = obj_list->begin(); i_obj != obj_list->end(); i_obj++)
	{
		obj = *i_obj;

		Box box(this->_xOld,
			this->_yOld - this->height, 
			width, 
			height, 
			veloc_x * time + 1.0f/2.0f * accel_x * time * time, 
			veloc_y * time  + 1.0f/2.0f * accel_y * time * time);

		Box block(obj->getPosX(),
			obj->getPosY() - obj->getHeight(),// - 0.11,
			obj->getWidth(),
			obj->getHeight(),
			obj->getVelocX() * time + 1.0f/2.0f * obj->getAccelX() * time * time, 
			obj->getVelocY() * time  + 1.0f/2.0f * obj->getAccelY() * time * time
			);

		Box boxphase = Collision::GetSweptBroadphaseBox(box);
		if (Collision::AABBCheck(boxphase, block))
		{
			float normalx = 0;
			float normaly = 0;
			float collision_time = Collision::SweptAABB(box, block, normalx, normaly);
			if (0 < collision_time && collision_time < 1)
			{
				isGravity = false;	//new
				/*
				*	Xet Huong Cua Va Cham
				*/
				if (normalx == 1 && normaly == 0)		//va cham tu phai -> trai
				{
					if (obj->getIDObjType() == 12)	//koopa
					{						
						if (isHasStar == false)	//chua co an sao
						{
							if (obj->getObjState() == ES_STOP)
							{
								obj->changeState(ES_MOVE_SHELL_LEFT);	//di chuyen sang trai
							}
							else if (obj->getObjState() == ES_MOVE_SHELL_LEFT || obj->getObjState() == ES_MOVE_SHELL_RIGHT)
							{
								if (isSmall == true)	//mario nho
								{
									game_Mario->num_Life--;
									game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
									game_Mario->dxAudio->PlaySound(game_Mario->deathSound);
									changeState(MS_DIE);	//mario chet
								}
								else					//mario lon
								{
									isSmall = true;
									if (isShoot == true)	//co bullet
									{
										changeState(MS_BULLETTOSMALL);
									} 
									else
									{
										changeState(MS_BIGTOSMALL);
									}
									isShoot = false;
								}
							}
						} 
						else
						{
							obj->changeState(ES_FALL);
						}
					}

					if (obj->getObjectType() == OBJECT_LAND)
					{
						/*pos_x = _xOld + veloc_x * collision_time + 1.0f/2.0f * accel_x * collision_time *collision_time;
						accel_x = 0;
						veloc_x = 0;*/
						if (this->_yOld - this->height < obj->getPosY())
						{
							pos_x = _xOld + veloc_x * collision_time + 1.0f/2.0f * accel_x * collision_time *collision_time;
							veloc_x = 0;						
							accel_x = 0;
						}
					}

				} 
				else if (normalx == -1 && normaly == 0)		//va cham tu trai -> phai
				{
					/*
					*	Xet va cham voi Koopa
					*/
					if (obj->getIDObjType() == 12)
					{						
						if (isHasStar == false)	//chua co an sao
						{
							if (obj->getObjState() == ES_STOP)
							{
								obj->changeState(ES_MOVE_SHELL_RIGHT);	//di chuyen sang phai
							}
							else if (obj->getObjState() == ES_MOVE_SHELL_LEFT || obj->getObjState() == ES_MOVE_SHELL_RIGHT)
							{
								if (isSmall == true)	//mario nho
								{
									game_Mario->num_Life--;
									game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
									game_Mario->dxAudio->PlaySound(game_Mario->deathSound);
									changeState(MS_DIE);	//mario chet
								}
								else					//mario lon
								{
									isSmall = true;
									if (isShoot == true)	//co bullet
									{
										changeState(MS_BULLETTOSMALL);
									} 
									else
									{
										changeState(MS_BIGTOSMALL);
									}
									isShoot = false;
								}
							}
						} 
						else
						{
							obj->changeState(ES_FALL);
						}
					}

					//xet va cham voi pine, chui cong len map chinh					
					if (obj->getIDObjType() == 29)	//ong ngang, de chui tu map phu len map chinh
					{
						Box block(this->pos_x,
							this->pos_y - this->height, 
							this->width, 
							this->height
							);

						Box box(obj->getPosX(),
							obj->getPosY() - obj->getHeight(),// - 0.11,
							obj->getWidth(),
							obj->getHeight()				
							);
						if (Collision::RectVsRect(box, block))
						{
							
							changeState(MS_INTOPINE);	//trang thai chui cong
							
						}
					}

					//xet va cham voi gach, da,..
					if (obj->getObjectType() == OBJECT_LAND)
					{
						/*pos_x = _xOld + veloc_x * collision_time + 1.0f/2.0f * accel_x * collision_time *collision_time;
						accel_x = 0;
						veloc_x = 0;*/
						if (this->_yOld - this->height < obj->getPosY())
						{
							pos_x = _xOld + veloc_x * collision_time + 1.0f/2.0f * accel_x * collision_time *collision_time;
							veloc_x = 0;						
							accel_x = 0;
						}
					}

				}
				else if (normalx == 0 && normaly == -1)		//va cham tu duoi -> tren
				{
					//Xet cac obj LAND
					if (obj->getObjectType() == OBJECT_LAND)
					{

						switch (obj->getIDObjType())
						{
						case 21:	//gach binh thuong
							if (obj->getObjState() == BS_NORMAL) //trang thai gach bt
							{
								if (this->isSmall == true)		//con nho
								{
									obj->changeState(BS_MOVEUP);
									//am thanh
									game_Mario->dxAudio->PlaySound(game_Mario->bumpSound);
								}
								else
								{
									obj->changeState(BS_BREAKING);

									game_Mario->dxAudio->PlaySoundW(game_Mario->brickBreakSound);
									game_Mario->InfoScore(50, obj->getPosX(), obj->getPosY() - 40);
									game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);
								}
							}
							break;
						case 25:	//gach dau hoi
							if (obj->getObjState() == BS_NORMAL) //trang thai gach bt
							{
								obj->changeState(BS_MOVEUP);								
							}
							break;
						case 26:	//gach an
							if (obj->getObjState() == BS_NORMAL) //trang thai gach bt
							{
								obj->changeState(BS_MOVEUP);
							}
							break;
						case 27:	//gach chua 5 coin
							if (obj->getObjState() == BS_NORMAL) //trang thai gach bt
							{
								obj->changeState(BS_MOVEUP);
							}
							break;
						case 28:	//gach cua sao
							if (obj->getObjState() == BS_NORMAL) //trang thai gach bt
							{
								obj->changeState(BS_MOVEUP);
							}
							break;

						}

						//pos_x = old_pos_x + veloc_x * collision_time + 1.0f/2.0f * accel_x * collision_time *collision_time;
						pos_y = _yOld + veloc_y * collision_time + 1.0f/2.0f * accel_y * collision_time *collision_time;
						veloc_y = 0;
						accel_y = 0;
					}

				}
				else if (normalx == 0 && normaly == 1)		//va cham tu tren -> duoi
				{
					/*
					*	Va cham voi Goomba, Koopa tu tren xuong
					*/
					switch (obj->getIDObjType())
					{
					case 11:	//Goomba
						if (isHasStar == false)	//chua an sao
						{
							if (obj->getObjState() == ES_ACTIVING)
							{
								game_Mario->InfoScore(100, obj->getPosX(), obj->getPosY() + 40);
								game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);
								game_Mario->dxAudio->PlaySound(game_Mario->mipSound);
								obj->changeState(ES_DIED);

								veloc_y = 2.0; //giam enemy rui nhay len
							}
						}
						else
						{
							obj->changeState(ES_FALL);
						}
						break;

					case 12:	//Koopba
						if (isHasStar == false)	//chua an sao
						{
							if (obj->getObjState() == ES_ACTIVING)
							{
								game_Mario->InfoScore(100, obj->getPosX(), obj->getPosY() + 40);
								game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);
								game_Mario->dxAudio->PlaySound(game_Mario->mipSound);
								obj->changeState(ES_STOP);	//con Rua dung lai

								veloc_y = 1.0; //giam enemy rui nhay len
							}
							else if (obj->getObjState() == ES_MOVE_SHELL_LEFT || obj->getObjState() == ES_MOVE_SHELL_RIGHT)
							{
								obj->changeState(ES_STOP);
								this->veloc_y = 2.0;
							}
						}
						else	//da an sao
						{
							obj->changeState(ES_FALL);
						}
						break;
					}

					//xet va cham voi pine, chui cong
					//xet va cham chui cong
					if (obj->getIDObjType() == 241) //ong co the chui xuong
					{
						Box block(this->pos_x,
							this->pos_y - this->height, 
							this->width, 
							this->height
							);

						Box box(obj->getPosX() + 24,
							obj->getPosY() - obj->getHeight(),
							16,//obj->getWidth()/2,
							obj->getHeight()				
							);
						if (Collision::RectVsRect(box, block))
						{
							if (isMoveDown == true)
							{
								isMoveDown = false;
								changeState(MS_CREPTPINE);	//trang thai chui cong
							}
						}
					}

					/*
					*	Kiem tra va cham voi cac gach, dat,...
					*/
					if (obj->getObjectType() == OBJECT_LAND)
					{
						pos_y = _yOld + veloc_y * collision_time + 1.0f/2.0f * accel_y * collision_time *collision_time + 0.11;
						is_jump = false;
						veloc_y = 0;
					}

				}
				//Ket thuc xet va cham theo huong
				


				/*
				*	va cham voi pirhana, coin, checkpoint
				*	goomba, koopba
				*/
				switch (obj->getIDObjType())
				{
				case 41:	//coin hien
					if (obj->getObjState() == IS_IDLE)
					{
						game_Mario->num_Coin++;
						game_Mario->scoreArr[COIN]->Update(game_Mario->num_Coin);
						game_Mario->InfoScore(200, obj->getPosX(), obj->getPosY() + 40);
						game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);

						game_Mario->dxAudio->PlaySoundW(game_Mario->coinSound);
						obj->changeState(IS_REMOVE);
					}
					break;

				case 51:	//check point
					//save map
					//chuyen map, state
					game_Mario->ChangeState(GS_NEXT_STAGE);
					break;

				case 43:	//va cham an nam mang: moving 					
					if (obj->getObjState() == IS_MOVING)
					{
						game_Mario->num_Life++;	//tang 1 mang
						game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
						//game_Mario->InfoScore(1000, obj->getPosX(), obj->getPosY() + 40);	//an nam tang 1000 diem
						//game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);
						game_Mario->dxAudio->PlaySound(game_Mario->bonusRiseSound);
						obj->changeState(IS_REMOVE);
					}
					break;

				case 44:	//va cham an sao: moving 
					if (obj->getObjState() == IS_MOVING)
					{
						game_Mario->num_Life++;	//tang 1 mang
						game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
						game_Mario->dxAudio->PlaySound(game_Mario->bonusRiseSound);
						obj->changeState(IS_REMOVE);
						this->isHasStar = true;
						this->changeState(MS_HASSTAR);
					}
					break;

				case 45:	//va cham an nam : moving, hoa:ready					
					if (obj->getObjState() == IS_MOVING || obj->getObjState() == IS_READY)
					{
						game_Mario->InfoScore(1000, obj->getPosX(), obj->getPosY() + 40);	//an nam tang 1000 diem
						game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);
						game_Mario->dxAudio->PlaySound(game_Mario->bonusRiseSound);
						obj->changeState(IS_REMOVE);
						if (this->isSmall == true)
						{
							this->isSmall = false;
							this->changeState(MS_SMALLTOBIG);
						}
						else
						{
							this->changeState(MS_BIGTOBULLET);
							this->isShoot = true;
						}
					}
					break;

				case 11:	//goomba
					if (isHasStar == false)	//chua co an sao
					{
						if (obj->getObjState() == ES_ACTIVING)
						{
							if (isSmall == true)	//mario nho
							{
								game_Mario->num_Life--;
								game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
								game_Mario->dxAudio->PlaySound(game_Mario->deathSound);
								changeState(MS_DIE);
							}
							else					//mario lon
							{
								isSmall = true;
								if (isShoot == true)	//co bullet
								{
									changeState(MS_BULLETTOSMALL);
								} 
								else
								{
									changeState(MS_BIGTOSMALL);
								}
								isShoot = false;
							}
						}
					} 
					else
					{
						obj->changeState(ES_FALL);
					}
					break;

				case 12:	//koopba
					/*
					*	Xet va cham voi Koopa
					*/					
					if (isHasStar == false)	//chua co an sao
					{
						if (obj->getObjState() == ES_ACTIVING)
						{
							if (isSmall == true)	//mario nho
							{
								game_Mario->num_Life--;
								game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
								game_Mario->dxAudio->PlaySound(game_Mario->deathSound);
								changeState(MS_DIE);	//mario chet
							}
							else					//mario lon
							{
								isSmall = true;
								if (isShoot == true)	//co bullet
								{
									changeState(MS_BULLETTOSMALL);
								} 
								else
								{
									changeState(MS_BIGTOSMALL);
								}
								isShoot = false;
							}
						}

					} 
					else
					{
						if (obj->getObjState() != ES_FALL)
						{
							obj->changeState(ES_FALL);
						}
					}
					break;

				}


				//xet trong luc cho mario
				//if (this->_yOld - this->height <= obj->getPosY() + 1.0)
				/*if (this->pos_y - this->p_sprite->getTexture()->getHeight() <= obj->getPosY() + 1.0)
				{
					isGravity = false;
				}
				else
				{
					isGravity = true;
				}*/


			}//Ket thuc co va cham
			else
			{
				isGravity = true;
			}



		}//Ket thuc co the co va cham
		else
		{
			isGravity = true;//new
			//xet trong luc cho mario
			/*if (this->pos_y - this->p_sprite->getTexture()->getHeight() <= obj->getPosY() + 1.5)
			{
				isGravity = false;
			}
			else
			{
				isGravity = true;
			}*/

		}



		//kiem tra dong tien da duoc an hay chua? active
		/*if (obj->getIDObjType() == 41 || obj->getIDObjType() == 46)
		{
			if (obj->getObjState() == IS_ACTIVING && obj->getIsChangeState() == true)
			{				
				game_Mario->num_Coin++;
				game_Mario->scoreArr[COIN]->Update(game_Mario->num_Coin);
				game_Mario->InfoScore(200, obj->getPosX(), obj->getPosY() - 40);
				game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);

				game_Mario->dxAudio->PlaySoundW(game_Mario->coinSound);

				obj->setIsChangeState(false);
			}
		}*/
		if (obj->getIDObjType() == 45)	//nam to, hoa
		{
			if (obj->getIsActiveMushroom() == true)
			{
				if (isSmall == true)
				{
					obj->changeState(IS_ACTIVING);
				}
				else
				{
					obj->changeState(IS_FLOWER);
				}

				obj->setIsActiveMushroom(false);
			}
		}
	}



	//Va cham Thong Thuong
	for (i_obj = obj_list->begin(); i_obj != obj_list->end(); i_obj++)
	{
		obj = *i_obj;		
		collisionOnTop(obj, obj_list, time);

		if (obj->getObjectType() == OBJECT_ENEMY || obj->getObjectType() == OBJECT_ITEM)		
		{ 
			Box block(this->_xOld,
				this->_yOld - this->height, 
				this->width, 
				this->height
				);
			Box box(obj->getPosX(),
				obj->getPosY() - obj->getHeight(),// - 0.11,
				obj->getWidth(),
				obj->getHeight()				
				);

			if (Collision::RectVsRect(box, block))
			{
				switch (obj->getIDObjType())
				{
				case 42:	//Cay an thit, pirhana
					if (obj->getObjState() == IS_ACTIVING)
					{
						if (isHasStar == false)		//chua an sao
						{
							if (isSmall == true)	//mario nho
							{
								changeState(MS_DIE);
								obj->changeState(ES_REMOVE);
							} 
							else					//mario lon
							{
								isSmall = true;
								if (isShoot == true)
								{
									changeState(MS_BULLETTOSMALL);
								} 
								else
								{
									changeState(MS_BIGTOSMALL);
								}
								isShoot = false;
								obj->changeState(ES_REMOVE);
							}
						} 
						else		//da an sao
						{
							obj->changeState(ES_REMOVE);
						}
					}
					break;

				case 43:	//va cham an nam mang: moving 
					if (obj->getObjState() == IS_MOVING)
					{
						game_Mario->num_Life++;	//tang 1 mang
						game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
						game_Mario->InfoScore(1000, obj->getPosX(), obj->getPosY() + 40);	//an nam tang 1000 diem
						game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);
						game_Mario->dxAudio->PlaySound(game_Mario->bonusRiseSound);
						obj->changeState(IS_REMOVE);
					}
					break;

				case 44:	//va cham an sao: moving 
					if (obj->getObjState() == IS_MOVING)
					{
						game_Mario->num_Life++;	//tang 1 mang
						game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
						game_Mario->dxAudio->PlaySound(game_Mario->bonusRiseSound);
						obj->changeState(IS_REMOVE);
						this->isHasStar = true;
						this->changeState(MS_HASSTAR);
					}
					break;

				case 45:	//va cham an nam : moving, hoa:ready					
					if (obj->getObjState() == IS_MOVING || obj->getObjState() == IS_READY)
					{
						game_Mario->InfoScore(1000, obj->getPosX(), obj->getPosY() + 40);	//an nam tang 1000 diem
						game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);
						game_Mario->dxAudio->PlaySound(game_Mario->bonusRiseSound);
						obj->changeState(IS_REMOVE);
						if (this->isSmall == true)
						{
							this->isSmall = false;
							this->changeState(MS_SMALLTOBIG);
						}
						else
						{
							this->changeState(MS_BIGTOBULLET);
							this->isShoot = true;
						}
					}
					break;


				case 11:	//goomba						
					if (isHasStar == false)	//chua co an sao
					{
						if (obj->getObjState() == ES_ACTIVING)
						{
							if (isSmall == true)	//mario nho
							{
								game_Mario->num_Life--;
								game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
								game_Mario->dxAudio->PlaySound(game_Mario->deathSound);
								changeState(MS_DIE);
							}
							else					//mario lon
							{
								isSmall = true;
								if (isShoot == true)	//co bullet
								{
									changeState(MS_BULLETTOSMALL);
								} 
								else
								{
									changeState(MS_BIGTOSMALL);
								}
								isShoot = false;
							}
						}
					} 
					else
					{
						obj->changeState(ES_FALL);
					}
					break;

				case 12:	//Koopa
					if (isHasStar == false)	//chua co an sao
					{
						if (obj->getObjState() == ES_ACTIVING)
						{
							if (isSmall == true)	//mario nho
							{
								game_Mario->num_Life--;
								game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
								game_Mario->dxAudio->PlaySound(game_Mario->deathSound);
								changeState(MS_DIE);	//mario chet
							}
							else					//mario lon
							{
								isSmall = true;
								if (isShoot == true)	//co bullet
								{
									changeState(MS_BULLETTOSMALL);
								} 
								else
								{
									changeState(MS_BIGTOSMALL);
								}
								isShoot = false;
							}
						}
						else if (obj->getObjState() == ES_MOVE_SHELL_LEFT || obj->getObjState() == ES_MOVE_SHELL_RIGHT)
						{
							if (isSmall == true)	//mario nho
							{
								game_Mario->num_Life--;
								game_Mario->scoreArr[NUMBER_LIFE]->Update(game_Mario->num_Life);
								game_Mario->dxAudio->PlaySound(game_Mario->deathSound);
								changeState(MS_DIE);	//mario chet
							}
							else					//mario lon
							{
								isSmall = true;
								if (isShoot == true)	//co bullet
								{
									changeState(MS_BULLETTOSMALL);
								} 
								else
								{
									changeState(MS_BIGTOSMALL);
								}
								isShoot = false;
							}
						}
					} 
					else
					{
						if (obj->getObjState() != ES_FALL)
						{
							obj->changeState(ES_FALL);
						}

					}

					break;

				}

			}

		}

	}
	//Ket thuc va cham thong thuong

	

	_xOld = pos_x;
	_yOld = pos_y;

	if (pos_y <= 10 && veloc_y < 0 && accel_y > 0)
	{
		veloc_y = 0;
		accel_y = 0;
		changeState(MS_DIE);
		
	}

	
	//Ngan mario rot xuong ma van con nhay duoc
	if (veloc_y < 0)
	{
		is_jump = true;
	}

	


	//chuyen dong cham lai do k nhan phim
	if (veloc_x < 0)
	{
		accel_x = ACCEL_X / 2;
	} 
	else if (veloc_x > 0)
	{
		accel_x = -ACCEL_X / 2;
	}
	else
	{
		accel_x = 0;
	}
	//tao chuyen dong dung lai
	if (accel_x * veloc_x < 0)
	{
		if (veloc_x > -ACCEL_X*3 && veloc_x < ACCEL_X*3)
		{
			veloc_x = 0;
			accel_x = 0;
		}
	}

}
/**--------------------------------------------------------
*Description : Render mario
*Method name : Render
*Parameters :  
*Return value :void
--------------------------------------------------------**/
void Mario::render(int cameraX, int cameraY)
{
	p_sprite->render((float)pos_x, (float)pos_y, cameraX, cameraY);

	if (bullet != NULL)
	{
		bullet->render(cameraX, cameraY);
	}
	if (bullet2 != NULL)
	{
		bullet2->render(cameraX, cameraY);
	}
}



/**--------------------------------------------------------
*Description : mario nhay sang trai
*Method name : TurnLeft
*Parameters :  
*Return value :void
--------------------------------------------------------**/
void Mario::turnLeft()
{
	is_turn_left = true;
	if (is_jump == true)
	{
		if (isSmall == true)
		{
			p_sprite->setFrame(8, 8);
		}
		else
		{
			p_sprite->setFrame(9, 9);
		}
	}
	else
	{
		if (isSmall == true)
		{
			p_sprite->setFrame(9, 11);
		} 
		else
		{
			p_sprite->setFrame(6, 9);
		}
	}
	//veloc_x = - MARIO_VX;
	accel_x = - ACCEL_X * 2;
}


/**--------------------------------------------------------
*Description : mario nhay sang phai
*Method name : TurnRight
*Parameters :  
*Return value :void
--------------------------------------------------------**/
void Mario::turnRight()
{
	is_turn_left = false;
	if (is_jump == true)
	{
		if (isSmall == true)
		{
			p_sprite->setFrame(2, 2);
		} 
		else
		{
			p_sprite->setFrame(0, 1);
		}
	}
	else
	{
		if (isSmall == true)
		{
			p_sprite->setFrame(0, 2);
		} 
		else
		{
			p_sprite->setFrame(1, 4);
		}
	}
	//veloc_x = MARIO_VX;
	accel_x = ACCEL_X * 2;

}


/**--------------------------------------------------------
*Description : mario nhay len
*Method name : Jump
*Parameters :  
*Return value :void
--------------------------------------------------------**/
void Mario::jump()
{
	if(!is_jump)
	{
		is_jump = true;
		if (is_turn_left == true)
		{
			if (isSmall == true)
			{
				p_sprite->setFrame(8, 8);
			} 
			else
			{
				p_sprite->setFrame(9, 9);
			}
		}
		else
		{
			if (isSmall == true)
			{
				p_sprite->setFrame(2, 2);
			} 
			else
			{
				p_sprite->setFrame(0, 1);
			}
		}
		veloc_y = MARIO_VY;
	}
}


/**--------------------------------------------------------
*Description : Mario tro ve ban dau
*Method name : Reset
*Parameters :  
*Return value :void
--------------------------------------------------------**/
void Mario::reset()
{
	if (is_turn_left == true)
	{
		if (is_jump == true)
		{
			if (isSmall == true)
			{
				p_sprite->setFrame(8, 8);
			} 
			else
			{
				p_sprite->setFrame(9, 9);
			}
		}
		else 
		{
			if (isSmall == true)
			{
				p_sprite->setFrame(10, 11);
			} 
			else
			{
				p_sprite->setFrame(8, 9);
			}

		}
	}
	else
	{
		if (is_jump == true)
		{
			if (isSmall == true)
			{
				p_sprite->setFrame(2, 2);
			} 
			else
			{
				p_sprite->setFrame(0, 1);
			}
		}
		else
		{
			if (isSmall == true)
			{
				p_sprite->setFrame(0, 1);
			} 
			else
			{
				p_sprite->setFrame(1, 2);
			}
		}
	}
}

void Mario::processInput(DxInput *p_input)
{
	//isMoveDown = false;

	//Dieu khien nhay
	int temp = p_input->GetKeyDown();
	switch (temp)
	{
	case DIK_UP:
	case DIK_SPACE:
		this->jump();
		game_Mario->dxAudio->PlaySoundW(game_Mario->jumpSound);		
		trace(L"Ban dang nhan phim Up hoac Space!");
		break;
	case DIK_DOWN:
		isMoveDown = true;
		trace(L"Ban dang nhan phim Up hoac Space!");
		break;
	}


	//State
	//Nhan phim va giu
	if (p_input->IsKeyDown(DIK_RIGHT))
	{
		this->turnRight();
		trace(L"Ban dang nhan phim Right!");
	}	
	else if (p_input->IsKeyDown(DIK_LEFT))
	{
		this->turnLeft();
		trace(L"Ban dang nhan phim Left!");
	}
	//else if (input->IsKeyDown(DIK_DOWN))
	//{
	//	//this->TurnLeft();
	//	_isMoveDown = true;
	//	trace(L"Ban dang nhan phim Down!");
	//}
	else
	{
		this->reset();
	}



	if (p_input->IsKeyDown(DIK_E))
	{
		if (timeBullet > 500 && isShoot == true)
		{

			if (is_turn_left == true)
			{
				bullet = new Bullet(d3ddv, backBuffer, spriteHandler, this->getPosX(), this->getPosY() - p_sprite->getTexture()->getHeight()/2, true);
				bullet2 = new Bullet(d3ddv, backBuffer, spriteHandler, this->getPosX() + p_sprite->getTexture()->getWidth()/2, this->getPosY() - p_sprite->getTexture()->getHeight()/2, true);
			}
			else
			{

				bullet = new Bullet(d3ddv, backBuffer, spriteHandler, this->getPosX(), this->getPosY() - p_sprite->getTexture()->getHeight()/2, false);
				bullet2 = new Bullet(d3ddv, backBuffer, spriteHandler, this->getPosX() + p_sprite->getTexture()->getWidth()/2, this->getPosY() - p_sprite->getTexture()->getHeight()/2, false);
			}			
			trace(L"Ban dang nhan phim E");
			timeBullet = 0;
		}

	}

}

D3DXVECTOR2 Mario::getPosition()
{
	D3DXVECTOR2 position;
	position.x = pos_x;
	position.y = pos_y;
	return position;
}

void Mario::collisionOnTop(Object* obj_brick,list<Object*>* obj_list, float time)
{
	if (obj_brick->getIDObjType() == 21 || obj_brick->getIDObjType() == 25 || obj_brick->getIDObjType() == 26 || obj_brick->getIDObjType() == 27 || obj_brick->getIDObjType() == 28)
	{
		Object* obj;
		list<Object*>::iterator iList;
		for (iList = obj_list->begin(); iList != obj_list->end(); iList++)
		{
			obj = *iList;

			Box block(obj_brick->getPosX(),
				obj_brick->getPosY() - this->getHeight(), 
				obj_brick->getWidth(), 
				obj->getHeight()
				);

			Box box(obj->getPosX(),
				obj->getPosY() - obj->getHeight(),// - 0.11,
				obj->getWidth(),
				obj->getHeight()				
				);
			if (Collision::RectVsRect(box, block))
			{
				if (obj_brick->getIsChangeState() == true)
				{					
					if (obj->getIDObjType() == 47 && obj->getObjState() == IS_IDLE)
					{

						obj->setContainer(obj_brick);

						obj->changeState(IS_ACTIVING);
						game_Mario->num_Coin++;
						game_Mario->scoreArr[COIN]->Update(game_Mario->num_Coin);
						game_Mario->InfoScore(200, obj->getPosX(), obj->getPosY() - 40);
						game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);

						game_Mario->dxAudio->PlaySoundW(game_Mario->coinSound);

						obj_brick->setIsChangeState(false);
					}
				}

				 switch (obj->getIDObjType())
				 {
				 case 41:
				 case 46:				 
					 if (obj->getObjState() == IS_IDLE)
					 {
						 obj->changeState(IS_ACTIVING);
						 //obj->setIsChangeState(true);
						 game_Mario->num_Coin++;
						 game_Mario->scoreArr[COIN]->Update(game_Mario->num_Coin);
						 game_Mario->InfoScore(200, obj->getPosX(), obj->getPosY() - 40);
						 game_Mario->scoreArr[SCORE]->Update(game_Mario->num_Score);

						 game_Mario->dxAudio->PlaySoundW(game_Mario->coinSound);
					 }
					 break;
				 }
			}


		}
	}



}

void Mario::changeState(int state)
{
	obj_state = state;
	switch (obj_state)
	{
	case MS_NORMAL:
		pos_y += 2;
		break;

	case MS_DIE:
		//mario nho
		if (is_turn_left == true)
		{
			p_sprite = p_spriteSmall;
			p_sprite->setFrame(6, 6);
		}
		else
		{
			p_sprite = p_spriteSmall;
			p_sprite->setFrame(4, 4);
		}
		veloc_y = 2.0;
		accel_y = GRAVITY;
		break;

	case MS_CREPTPINE:			//chui cong
		accel_y = GRAVITY/10;
		break;

	case MS_INTOPINE:			//chui vao cong
		accel_x = ACCEL_X * 2;
		_xOld = pos_x;
		break;

	case MS_REMOVE:
		break;

	case MS_SMALLTOBIG:
		timeTransferState = 0;
		countFrame = 0;
		break;

	case MS_BIGTOSMALL:
		timeTransferState = 0;
		countFrame = 0;
		break;

	case MS_BIGTOBULLET:
		timeTransferState = 0;
		countFrame = 0;
		break;

	case MS_BULLETTOSMALL:
		timeTransferState = 0;
		countFrame = 0;
		break;

	case MS_PROTECT:
		timeProtect = 0;
		countFrame = 0;
		break;

	case MS_HASSTAR:
		timeProtect = 0;
		countFrame = 0;
		break;

	}
}